<?php

namespace app\api\service;

use app\common\BaseHelper;
use app\admin\model\Member;
use app\lib\exception\WeChatException;
use think\Exception;

class UserToken extends Token
{

    protected $code;
    protected $uid;
    protected $wxLoginUrl;
    protected $wxAppID;
    protected $wxAppSecret;

    function __construct($code,$uid)
    {
        $this->code = $code;
        $this->uid = $uid;
        $this->wxAppID = config('wx.app_id');
        $this->wxAppSecret = config('wx.app_secret');
        $this->wxLoginUrl = sprintf(
            config('wx.login_url'), $this->wxAppID, $this->wxAppSecret, $this->code);
    }


    /**
     * 登陆
     * 思路1：每次调用登录接口都去微信刷新一次session_key，生成新的Token，不删除久的Token
     * 思路2：检查Token有没有过期，没有过期则直接返回当前Token
     * 思路3：重新去微信刷新session_key并删除当前Token，返回新的Token
     */
    public function get()
    {
        $result = BaseHelper::curlGet($this->wxLoginUrl);

        // 注意json_decode的第一个参数true
        // 这将使字符串被转化为数组而非对象

        $wxResult = json_decode($result, true);
        if (empty($wxResult)) {
            // 为什么以empty判断是否错误，这是根据微信返回
            // 规则摸索出来的
            // 这种情况通常是由于传入不合法的code
            throw new Exception('获取session_key及openID时异常，微信内部错误');
        }
        else {
            // 建议用明确的变量来表示是否成功
            // 微信服务器并不会将错误标记为400，无论成功还是失败都标记成200
            // 这样非常不好判断，只能使用errcode是否存在来判断
            $loginFail = array_key_exists('errcode', $wxResult);
            if ($loginFail) {
                $this->processLoginError($wxResult);
            }
            else {
                return $this->getorsaveOpenid($wxResult);
            }
        }
    }

    // 判断是否重复获取
    private function duplicateFetch(){
        //TODO:目前无法简单的判断是否重复获取，还是需要去微信服务器去openid
        //TODO: 这有可能导致失效行为
    }

    // 处理微信登陆异常
    // 那些异常应该返回客户端，那些异常不应该返回客户端
    // 需要认真思考
    private function processLoginError($wxResult)
    {
        throw new WeChatException(
            [
                'msg' => $wxResult['errmsg'],
                'errorCode' => $wxResult['errcode']
            ]);
    }

    private function getorsaveOpenid($wxResult)
    {
        $openid = $wxResult['openid'];
        if(!empty($this->uid)){
            $user = Member::getByUid($this->uid);
            $userOpenid = Member::getByOpenId($openid);
            if(!$userOpenid){
                if ($user){
                    if(empty($user->open_id)){
                        $user->open_id = $openid;
                        $user->save();
                    }
                }
            }
        }
        return $openid;
    }

}
